﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chapter14
{
    using System.Collections;
    using System.Globalization;
    using System.Threading;
    using System.Windows.Forms;
    using System.Security;
    using System.Runtime.InteropServices;

    partial class Program
    {
        internal static void Begin(Action action, bool active = false)
        {
            if (active)
            {
                Console.WriteLine("开始演示：");
                action();
                Console.WriteLine("演示完毕：");
                Console.ReadLine();
            }
        }

        internal static void C01()
        {
            {
                double d;
                d = char.GetNumericValue('\u0033');
                Console.WriteLine(d.ToString());
                d = char.GetNumericValue('\u00bc');
                Console.WriteLine(d.ToString());
                d = char.GetNumericValue('A');
                Console.WriteLine(d.ToString());
            }
            {
                char c;
                int n;
                c = (char)65;
                Console.WriteLine(c);
                n = (int)c;
                Console.WriteLine(n);
                c = unchecked((char)(65536 + 65));
                Console.WriteLine(c);
                c = Convert.ToChar(65);
                Console.WriteLine(c);
                n = Convert.ToInt32(c);
                Console.WriteLine(n);
                try
                {
                    c = Convert.ToChar(70000);
                }
                catch (OverflowException)
                {
                    Console.WriteLine("Can't convert 70000 to a Char.");
                }
            }
        }

        internal static void C02()
        {
            {
                string s = "Hi there";
                Console.WriteLine(s);
            }
            {
                string s = "Hi\r\nthere.";
                Console.WriteLine(s);
            }
            {
                string s = "Hi " + " " + "there.";
                Console.WriteLine(s);
            }
            {
                string s = "Hi" + Environment.NewLine + "there.";
                Console.WriteLine(s);
            }
            {
                string file = "C:\\Windows\\System32\\Notepad.exe";
                Console.WriteLine(file);
            }
            {
                string file = @"C:\Windows\System32\Notepad.ext";
                Console.WriteLine(file);
            }
            {
                string s1 = "Strasse";
                string s2 = "Straße";
                bool eq;
                eq = string.Compare(s1, s2, StringComparison.Ordinal) == 0;
                Console.WriteLine("Ordinal comparison: '{0}' {2} '{1}'", s1, s2, eq ? "==" : "!=");
                CultureInfo ci = new CultureInfo("de-DE");
                eq = string.Compare(s1, s2, true, ci) == 0;
                Console.WriteLine("Ordinal comparison: '{0}' {2} '{1}'", s1, s2, eq ? "==" : "!=");
            }
            {
                string output = string.Empty;
                string[] symbol = new string[] { "<", "=", ">" };
                int x;
                CultureInfo ci;
                string s1 = "coté";
                string s2 = "côte";
                ci = new CultureInfo("fr-FR");
                x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
                output += string.Format("{0} Compare: {1} {3} {2}", ci.Name, s1, s2, symbol[x + 1]);
                output += Environment.NewLine;
                ci = new CultureInfo("ja-JP");
                x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
                output += string.Format("{0} Compare: {1} {3} {2}", ci.Name, s1, s2, symbol[x + 1]);
                output += Environment.NewLine;
                ci = Thread.CurrentThread.CurrentCulture;
                x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
                output += string.Format("{0} Compare: {1} {3} {2}", ci.Name, s1, s2, symbol[x + 1]);
                output += Environment.NewLine;
                s1 = "しんかんせん";
                s2 = "シンカンセン";
                ci = new CultureInfo("ja-JP");
                x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
                output += string.Format("{0} Compare: {1} {3} {2}", ci.Name, s1, s2, symbol[x + 1]);
                output += Environment.NewLine;
                CompareInfo compareInfo = CompareInfo.GetCompareInfo("ja-JP");
                x = Math.Sign(compareInfo.Compare(s1, s2, CompareOptions.IgnoreKanaType));
                output += string.Format("{0} Compare: {1} {3} {2}", ci.Name, s1, s2, symbol[x + 1]);
                output += Environment.NewLine;
                MessageBox.Show(output, "Comparing String For Sorting");
            }
            {
                string s = "a\u0304\u0308bc\u0327";
                SubstringByTextElements(s);
                EnumTextElements(s);
                EnumTextElementIndexes(s);
            }
        }

        private static int NumTimesWordAppearsEquals(string word, string[] wordlist)
        {
            int count = 0;
            for (int i = 0; i < wordlist.Length; i++)
            {
                if (word.Equals(wordlist[i], StringComparison.Ordinal))
                    count++;
            }
            return count;
        }

        private static int NumTimesWordAppearsIntern(string word, string[] wordlist)
        {
            word = string.Intern(word);
            int count = 0;
            for (int i = 0; i < wordlist.Length; i++)
            {
                if (object.ReferenceEquals(word, wordlist[i]))
                    count++;
            }
            return count;
        }

        private static void SubstringByTextElements(string s)
        {
            string output = string.Empty;
            StringInfo si = new StringInfo(s);
            for (int i = 0; i < si.LengthInTextElements; i++)
            {
                output += string.Format("Text element {0} is '{1}'{2}", i, si.SubstringByTextElements(i, 1), Environment.NewLine);
            }
            MessageBox.Show(output, "Result of SubstringByElements");
        }

        private static void EnumTextElements(string s)
        {
            string output = string.Empty;
            TextElementEnumerator charEnum = StringInfo.GetTextElementEnumerator(s);
            while (charEnum.MoveNext())
            {
                output += string.Format("Character at index {0} is '{1}'{2}", charEnum.ElementIndex, charEnum.GetTextElement(), Environment.NewLine);
            }
            MessageBox.Show(output, "Result of GetTextElementEnumerator");
        }

        private static void EnumTextElementIndexes(string s)
        {
            string output = string.Empty;
            int[] textElemIndex = StringInfo.ParseCombiningCharacters(s);
            for (int i = 0; i < textElemIndex.Length; i++)
            {
                output += string.Format("Character {0} starts at index {1} {2}", i, textElemIndex[i], Environment.NewLine);
            }
            MessageBox.Show(output, "Result of ParseCombiningCharacters");
        }

        internal static void C03()
        {
            {
                StringBuilder sb = new StringBuilder();
                string s = sb.AppendFormat("{0} {1}", "Jeffrey", "Richter").Replace(' ', '-').Remove(4, 3).ToString();
                Console.WriteLine(s);
            }
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("{0} {1}", "Jeffrey", "Richter").Replace(' ', '-');
                string s = sb.ToString().ToUpper();
                sb.Length = 0;
                sb.Append(s).Insert(8, "Marc-");
                s = sb.ToString();
                Console.WriteLine(s);
            }
        }

        internal static void C04()
        {
            {
                decimal price = 123.54M;
                string s = price.ToString("C", new CultureInfo("vi-VN"));
                MessageBox.Show(s);
            }
            {
                decimal price = 123.54M;
                string s = price.ToString("C", CultureInfo.InvariantCulture);
                MessageBox.Show(s);
            }
            {
                string s = string.Format("On {0}, {1} is {2} years old.", DateTime.Now, "Aidan", 7);
                Console.WriteLine(s);
            }
            {
                string s = string.Format("On {0:D}, {1} is {2:E} years old.", DateTime.Now, "Aidan", 7);
                Console.WriteLine(s);
            }
            {
                string s = string.Format(new BoldInt32s(), "On {0}, {1} is {2} years old.", DateTime.Now, "Aidan", 7);
                Console.WriteLine(s);
            }
        }

        private sealed class BoldInt32s : IFormatProvider, ICustomFormatter
        {

            public object GetFormat(Type formatType)
            {
                if (formatType == typeof(ICustomFormatter))
                    return this;
                return Thread.CurrentThread.CurrentCulture.GetFormat(formatType);
            }

            public string Format(string format, object arg, IFormatProvider formatProvider)
            {
                string s;
                IFormattable formattable = arg as IFormattable;
                if (formattable == null)
                    s = arg.ToString();
                else
                    s = formattable.ToString(format, formatProvider);
                if (arg.GetType() == typeof(int))
                    return "<B>" + s + "</B>";
                return s;
            }
        }

        internal static void C05()
        {
            {
                int x = int.Parse(" 123", NumberStyles.AllowLeadingWhite, null);
                Console.WriteLine(x);
            }
            {
                int x = int.Parse("1A", NumberStyles.HexNumber, null);
                Console.WriteLine(x);
            }
        }

        internal static void C06()
        {
            {
                string s = "Hi, there.";
                Encoding encodingUTF8 = Encoding.UTF8;
                byte[] encodingBytes = encodingUTF8.GetBytes(s);
                Console.WriteLine("Encoded bytes: " + BitConverter.ToString(encodingBytes));
                string decodedString = encodingUTF8.GetString(encodingBytes);
                Console.WriteLine("Decoded string: " + decodedString);
            }
            {
                foreach (EncodingInfo item in Encoding.GetEncodings())
                {
                    Encoding e = item.GetEncoding();
                    Console.WriteLine("{1}{0}" +
                        "\tCodePage={2}, WindowsCodePage={3}{0}" +
                        "\tWebName={4}, HeaderName={5}, BodyName={6}{0}" +
                        "\tIsBrowserDisplay={7}, IsBrowserSave={8}{0}" +
                        "\tIsMailNewDisplay={9}, IsMailNewsSave={10}{0}",
                        Environment.NewLine,
                        e.EncodingName,
                        e.CodePage, e.WindowsCodePage,
                        e.WebName, e.HeaderName, e.BodyName,
                        e.IsBrowserDisplay, e.IsBrowserSave,
                        e.IsMailNewsDisplay, e.IsMailNewsSave);
                }
            }
            {
                byte[] bytes = new byte[10];
                new Random().NextBytes(bytes);
                Console.WriteLine(BitConverter.ToString(bytes));
                string s = Convert.ToBase64String(bytes);
                Console.WriteLine(s);
                bytes = Convert.FromBase64String(s);
                Console.WriteLine(BitConverter.ToString(bytes));
            }
            {
                using (SecureString ss = new SecureString())
                {
                    Console.Write("Please enter password: ");
                    while (true)
                    {
                        ConsoleKeyInfo cki = Console.ReadKey(true);
                        if (cki.Key == ConsoleKey.Enter)
                            break;
                        ss.AppendChar(cki.KeyChar);
                        Console.Write("*");
                    }
                    Console.WriteLine();
                }
            }
        }
    }
}
